
#include "stdafx.h"
#include "StackWnd.h"
#include "Resource.h"
#include "MainFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CStackWnd

CStackWnd::CStackWnd()
{
}

CStackWnd::~CStackWnd()
{
}

BEGIN_MESSAGE_MAP(CStackWnd, CDockablePane)
    ON_WM_CREATE()
    ON_WM_SIZE()
END_MESSAGE_MAP()

int CStackWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if( CDockablePane::OnCreate( lpCreateStruct ) == -1 )
        return -1;

    CRect rectDummy( 0, 0, 400, 200 );
    if( !m_listCtrl.Create( WS_CHILD|WS_VISIBLE|WS_BORDER|LVS_REPORT|LVS_EDITLABELS|WS_HSCROLL|WS_VSCROLL|LVS_SINGLESEL, 
        rectDummy, this, IDD_STACK_LISTCTRL ) )
    {
        TRACE0("Failed to create output tab window\n");
        return -1;      // fail to create
    }
    
    m_listCtrl.SetExtendedStyle( LVS_EX_FLATSB|LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT );

    m_listCtrl.InsertColumn( 0, "#", LVCFMT_LEFT, 40 );
    m_listCtrl.InsertColumn( 1, "Access", LVCFMT_LEFT, 80 );
    m_listCtrl.InsertColumn( 2, "Type", LVCFMT_LEFT, 100 );
    m_listCtrl.InsertColumn( 3, "Data", LVCFMT_LEFT, 200 );

    /*m_listCtrl.InsertItem( LVIF_TEXT | LVIF_STATE, 0, "0", 0, LVIS_SELECTED, 0, 0 );
    m_listCtrl.SetItemText( 0, 1, "sys" );
    m_listCtrl.SetItemText( 0, 2, "sys" );
    m_listCtrl.SetItemText( 0, 4, "0000000000000000" );*/

    return 0;
}

void CStackWnd::OnSize(UINT nType, int cx, int cy)
{
    CDockablePane::OnSize(nType, cx, cy);

    // Tab control should cover the whole client area:
    m_listCtrl.SetWindowPos( NULL, -1, -1, cx, cy, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
}

void CStackWnd::AddCellInfo( const XortElement& cell )
{
    CString cs0, cs1, cs2, cs3;

    cs0.Format( "%d", m_listCtrl.GetItemCount() );

    if( cell.bAccess & sys_Frame ) {
        cs1 = "sys";
        cs2.Format( "argNo: %d", cell.bType );
        cs3.Format( "stkBase: %d", cell._asp );
    } else if( cell.bAccess & sys_Scope ) {
        cs1 = "frame";
        cs2.Format( "rsvd: %02X", cell.bType );
        cs3.Format( "%d", cell._asp );
    } else if( cell.bAccess & usr_VarRW ) {
        cs1 = "usrR/W";
    } else if( cell.bAccess & usr_VarR ) {
        cs1 = "usrR";
    } else {
        cs1.Format( "%02X", cell.bAccess );
    }

    if( cell.bAccess & usr_VarRW || cell.bAccess & usr_VarR )
    {
        string csTemp = xFormatElementValue( const_cast<XortElement&>( cell ), 16 );
        cs3 = csTemp.GetBuffer();

        switch( cell.bType ) 
        {
        case t_v:  cs2 = "void";   break;
        case t_s1: cs2 = "char";   break;
        case t_u1: cs2 = "byte";   break;
        case t_s2: cs2 = "short";  break;
        case t_u2: cs2 = "word";   break;
        case t_s4: cs2 = "int";    break;
        case t_u4: cs2 = "dword";  break;
        case t_s8: cs2 = "long";   break;
        case t_u8: cs2 = "qword";  break;
        case t_r4: cs2 = "float";  break;
        case t_r8: cs2 = "double"; break;
        case t_p:  
            if( cell._p != NULL ) {
                dword dwType = ((xobject*)cell._p)->GetType();
                if( dwType == t_string ) cs2 = "string";
                else if( dwType == t_array ) cs2 = "array";
                else if( dwType == t_list ) cs2 = "list";
                else cs2 = "object";
            } else {
                cs2 = "object";
            }
            break;
        default:   cs2 = "<?>";    break;
        }
        
    }
        
    int iIdx = m_listCtrl.InsertItem( LVIF_TEXT | LVIF_STATE, m_listCtrl.GetItemCount(), cs0, 0, LVIS_SELECTED, 0, 0 );
    m_listCtrl.SetItemText( iIdx, 1, cs1 );
    m_listCtrl.SetItemText( iIdx, 2, cs2 );
    m_listCtrl.SetItemText( iIdx, 3, cs3 );

    m_listCtrl.EnsureVisible( iIdx, FALSE );
}

void CStackWnd::Clear()
{
    m_listCtrl.DeleteAllItems();
}